from PySide6.QtCore import QThread, Signal
import paramiko
import socket
import time
from datetime import datetime
import os
from .base_thread import BaseThread

class SSHThread(BaseThread):
    def __init__(self, host, port, username, password):
        super().__init__()
        self.host = host
        self.port = int(port)
        self.username = username
        self.password = password
        self.client = None
        self.channel = None
        
    def _connect(self):
        """建立SSH连接"""
        retry_count = 3
        retry_delay = 2  # 重试间隔秒数
        last_error = None

        for attempt in range(retry_count):
            try:
                if attempt > 0:
                    self.error.emit(f"第{attempt}次重试连接...")
                    time.sleep(retry_delay)

                self.client = paramiko.SSHClient()
                self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                
                # 添加详细的连接状态信息
                self.error.emit(f"正在连接到 {self.username}@{self.host}:{self.port}...")
                
                self.client.connect(
                    hostname=self.host,
                    port=self.port,
                    username=self.username,
                    password=self.password,
                    timeout=10,  # 设置连接超时时间
                    allow_agent=False,  # 禁用SSH代理
                    look_for_keys=False  # 禁用自动密钥查找
                )

                self.channel = self.client.invoke_shell()
                self._is_running = True
                
                # SSH连接成功
                self.connected.emit(True)
                return True

            except paramiko.AuthenticationException as e:
                last_error = "认证失败：用户名或密码错误"
                break  # 认证失败不需要重试
            except paramiko.SSHException as e:
                last_error = f"SSH连接错误：{str(e)}"
            except socket.timeout:
                last_error = "连接超时"
            except socket.error as e:
                last_error = f"网络错误：{str(e)}"
            except Exception as e:
                last_error = f"未知错误：{str(e)}"

        # 所有重试都失败后
        if last_error:
            self.error.emit(last_error)
            self.connected.emit(False)
            self._cleanup()
        return False

    def _cleanup(self):
        """清理连接资源"""
        if self.channel:
            try:
                self.channel.close()
            except:
                pass
            self.channel = None

        if self.client:
            try:
                self.client.close()
            except:
                pass
            self.client = None
        
        self._is_running = False
    
    def _disconnect(self):
        try:
            if self.channel and self.channel.active:
                self.channel.close()
            if self.client:
                self.client.close()
            self.is_connected = False
        except (EOFError, Exception) as e:
            # 忽略EOFError，因为这通常意味着连接已经关闭
            self.is_connected = False
        self._cleanup()
    
    def write(self, data):
        if self.channel:
            try:
                self.channel.send(data)
            except Exception as e:
                self.error.emit(str(e))
    
    def is_connected(self):
        return self.channel is not None and self.client is not None and self.channel.active
    
    def get_connection_info(self):
        return f"SSH - {self.username}@{self.host}:{self.port}"
    
    def _read_data(self):
        if self.channel and self.channel.recv_ready():
            data = self.channel.recv(1024).decode('utf-8', errors='ignore')
            if data:
                self.received.emit(data)